﻿using System;
using System.Collections.Generic;
using System.Reflection;

namespace Fadd.System
{
    /// <summary>
    /// Contains information about all types that was found in an assembly during type searching.
    /// </summary>
    /// <remarks>
    /// The class contains the assembly location and all found types that are defined in it.
    /// </remarks>
    /// <seealso cref="AssemblyTypeScanner"/>
    public class TypeInformation
    {
        private readonly string _assembly;
        private readonly string _publicKey;
        private readonly byte[] _publicKeyRaw;
        private readonly List<Type> _types = new List<Type>();

        /// <summary>
        /// Initializes a new instance of the <see cref="TypeInformation"/> class.
        /// </summary>
        /// <param name="assemblyLocation">assembly that the plugin resides in.</param>
        /// <param name="type">plugin type.</param>
        /// <param name="publicKey">assemblies public key. should be used to decide the amount of access for the module.</param>
        public TypeInformation(string assemblyLocation, Type type, byte[] publicKey)
        {
            if (type == null)
                throw new ArgumentNullException("type");
            if (assemblyLocation == null)
                throw new ArgumentNullException("assemblyLocation");

            _assembly = assemblyLocation;
            _types.Add(type);
            _publicKey = string.Empty;
            _publicKeyRaw = publicKey;
            if (publicKey != null)
            {
                for (int i = 0; i < publicKey.Length; ++i)
                    _publicKey += publicKey[i].ToString("x2");
            }
        }

        /// <summary>
        /// Get asssembly location
        /// </summary>
        /// <remarks>
        /// Use <see cref="Assembly.Load"/> on this location.
        /// </remarks>
        public string Location
        {
            get { return _assembly; }
        }

        /// <summary>
        /// Assemblies public key if signed.
        /// </summary>
        public string PublicKey
        {
            get { return _publicKey; }
        }

        /// <summary>
        /// Assembly public key in byte format.
        /// </summary>
        public byte[] PublicKeyRaw
        {
            get { return _publicKeyRaw; }
        }

        /// <summary>
        /// Gets all types found in this assembly
        /// </summary>
        /// <remarks>
        /// All types that you requested during scanning.
        /// </remarks>
        public IEnumerable<Type> Types
        {
            get { return _types; }
        }

        /// <summary>
        /// Add another found type.
        /// </summary>
        /// <param name="type"></param>
        public void Add(Type type)
        {
            if (type == null)
                throw new ArgumentNullException("type");

            _types.Add(type);
        }
    }
}